package com.cweb.admin.configuration;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.cweb.admin.configuration.annotation.NoAuthorityCheck;
import com.cweb.admin.configuration.annotation.NoLoginCheck;
import com.cweb.admin.serivce.authority.AuthorityJWTService;
import com.cweb.admin.serivce.authority.UserLoginService;
import com.cweb.admin.serivce.authority.UserLoginToken;
import com.cweb.framework.pojo.CustomException;
import com.cweb.framework.util.ErrorEnum;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class LoginInterceptor {
    private static final Log log = LogFactory.get();
    @Autowired
    private UserLoginService userLoginService;
    @Autowired
    private AuthorityJWTService authorityJWTService;

    @Pointcut("execution(* com.cweb..controller..*(..)) && " +
            "(@annotation(org.springframework.web.bind.annotation.RequestMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
            "@annotation(org.springframework.web.bind.annotation.PostMapping) )")
    private void controllerAspect() {
    }

    /**
     * 前置处理
     */
    @Before(value = "controllerAspect()")
    public void beforeService(JoinPoint joinPoint) throws CustomException {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) requestAttributes
                .resolveReference(RequestAttributes.REFERENCE_REQUEST);
        // 用户权限验证
        try {
            UserLoginToken loginToken = authorityJWTService.checkAuthority(request);
            log.info("用户信息：{}({}/{})", loginToken.getName(), loginToken.getId(), loginToken.getType());
        } catch (CustomException e) {
            if (ErrorEnum.USER_LOGIN_TOKEN_NO_AUTHORITY.getCode().equals(e.getCode()) && null != ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(NoAuthorityCheck.class)) {
                // 接口方法带有NoAuthorityCheck注解，且异常原因是没有对应权限时，不跳出
            } else if (null != ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(NoLoginCheck.class)) {
                // 接口方法带有NoLoginCheck注解时，不跳出
            } else {
                throw e;
            }
        }
    }

    /**
     * 后置处理
     */
    @After(value = "controllerAspect()")
    public void afeter(JoinPoint joinPoint) throws CustomException {
        userLoginService.removeCurLoginToken();
    }
}
